package Finance

import scalaj.http.Http



class YahooQuoteCaller {

	val QURLBase = "http://download.finance.yahoo.com/d/quotes.csvr?e=.csv&f=";
	var QURLFormat = "snl1d1t1c1p2va2bapomwerr1dyj1x";	// default up to 0.19
	val QURLExtended = "s7t8e7e8e9r6r7r5b4p6p5j4m3m4";	// new in 0.20
	val QURLRealtime = "b2b3k2k1c6m2j3";//  also new in 0.20
	val QURLEnd = "&s=";
	var QURL = QURLBase + QURLFormat +QURLEnd;//  define old format as default

	val fields = scala.collection.immutable.HashMap[String,String](
			"Symbol"				->  "s",	// old default
			"Name"				->  "n",	// old default
			"Last Trade (With Time)"		->  "l",
			"Last Trade (Price Only)"		->  "l1",	// old default
			"Last Trade Date"			->  "d1",	// old default
			"Last Trade Time"			->  "t1",	// old default
			"Last Trade Size"			->  "k3",
			"Change and Percent Change"	->  "c",
			"Change"				->  "c1",	// old default
			"Change in Percent"		->  "p2",	// old default
			"Ticker Trend"			->  "t7",
			"Volume"				->  "v",	// old default
			"Average Daily Volume"		->  "a2",	// old default
			"More Info"			->  "i",
			"Trade Links"			->  "t6",
			"Bid"				->  "b",	// old default
			"Bid Size"			->  "b6",
			"Ask"				->  "a",	// old default
			"Ask Size"			->  "a5",
			"Previous Close"			->  "p",	// old default
			"Open"				->  "o",	// old default
			"Day's Range"			->  "m",	// old default
			"52-week Range"			->  "w",	// old default
			"Change From 52-wk Low"		->  "j5",
			"Pct Chg From 52-wk Low"		->  "j6",
			"Change From 52-wk High"		->  "k4",
			"Pct Chg From 52-wk High"		->  "k5",
			"Earnings/Share"			->  "e",	// old default
			"P/E Ratio"			->  "r",	// old default
			"Short Ratio"			->  "s7",
			"Dividend Pay Date"		->  "r1",	// old default
			"Ex-Dividend Date"		->  "q",
			"Dividend/Share"			->  "d",	// old default
			"Dividend Yield"			->  "y",	// old default
			"Float Shares"			->  "f6",
			"Market Capitalization"		->  "j1",	// old default
			"1yr Target Price"		->  "t8",
			"EPS Est. Current Yr"		->  "e7",
			"EPS Est. Next Year"		->  "e8",
			"EPS Est. Next Quarter"		->  "e9",
			"Price/EPS Est. Current Yr"	->  "r6",
			"Price/EPS Est. Next Yr"		->  "r7",
			"PEG Ratio"			->  "r5",
			"Book Value"			->  "b4",
			"Price/Book"			->  "p6",
			"Price/Sales"			->  "p5",
			"EBITDA"				->  "j4",
			"50-day Moving Avg"		->  "m3",
			"Change From 50-day Moving Avg"	->  "m7",
			"Pct Chg From 50-day Moving Avg"	->  "m8",
			"200-day Moving Avg"		->  "m4",
			"Change From 200-day Moving Avg"	->  "m5",
			"Pct Chg From 200-day Moving Avg"	->  "m6",
			"Shares Owned"			->  "s1",
			"Price Paid"			->  "p1",
			"Commission"			->  "c3",
			"Holdings Value"			->  "v1",
			"Day's Value Change"		->  "w1",
			"Holdings Gain Percent"		->  "g1",
			"Holdings Gain"			->  "g4",
			"Trade Date"			->  "d2",
			"Annualized Gain"			->  "g3",
			"High Limit"			->  "l2",
			"Low Limit"			->  "l3",
			"Notes"				->  "n4",
			"Last Trade (Real-time) with Time"->  "k1",
			"Bid (Real-time)"			->  "b3",
			"Ask (Real-time)"			->  "b2",
			"Change Percent (Real-time)"	->  "k2",
			"Change (Real-time)"		->  "c6",
			"Holdings Value (Real-time)"	->  "v7",
			"Day's Value Change (Real-time)"	->  "w4",
			"Holdings Gain Pct (Real-time)"	->  "g5",
			"Holdings Gain (Real-time)"	->  "g6",
			"Day's Range (Real-time)"		->  "m2",
			"Market Cap (Real-time)"		->  "j3",
			"P/E (Real-time)"			->  "r2",
			"After Hours Change (Real-time)"	->  "c8",
			"Order Book (Real-time)"		->  "i5",
			"Stock Exchange"			->  "x");


	// simple function to switch to extended format
	def useExtendedQueryFormat {
		if(!QURLFormat.contains(QURLExtended)){
			QURLFormat += QURLExtended;
		}
	}

	// simple function to append real-time format
	def useRealtimeQueryFormat {
		if(!QURLFormat.contains(QURLRealtime)){
			QURLFormat += QURLRealtime;
		}
	}

	// allow module user to define a new query string
	def setQueryString(format:String) {

		QURLFormat = format;
	}


	def getQuote(symbols:List[String]) : List[Array[String]] = {

			println("Yahoo Finance Caller : getQuote")

			readYahoo(symbols,QURLFormat);// Old default from variable

	}


	def getOneQuote(symbol:String) : List[Array[String]] = {

			println("Yahoo Finance Caller : getOneQuote")

			readYahoo(List(symbol),QURLFormat);// Old default from variable

	}

	def readYahoo(symbols:List[String],format:String) : List[Array[String]] = {


			var localSymbols:List[String] = symbols

			var listOfArray:List[Array[String]] = List[Array[String]]()


			//Loop over the list of symbols, grabbing 199 symbols at a 
			//time, since yahoo only lets you get 200 per request
			while (localSymbols.length != 0 ) {


				val b = getSymbolsInProperCount(localSymbols)
				localSymbols = trimSymbolsInProperCount(localSymbols)

				val url = QURLBase + format + QURLEnd + getSymbolsFromList(b)
				println(url)

				val httpResult:String = Http(url).asString
				val arrOfLines= httpResult.split('\n')

				for(ind <- 0 until arrOfLines.length){
					val arrLine:Array[String]= arrOfLines(ind).split(',')

					listOfArray = listOfArray :+ arrLine

				}

			}


	listOfArray


	}

	def getSymbolsFromList(symbols:List[String]) : String = {

			symbols.mkString("+")

	}

	def getSymbolsInProperCount(symbols:List[String]) : List[String] = {
			if(symbols.length >= 200 ){	
				symbols.slice(0,200);  
			}
			else{
				symbols.slice(0,symbols.length);
			}
	}

	def trimSymbolsInProperCount(symbols:List[String]) : List[String] = {
			if(symbols.length >= 200 ){	
				symbols.slice(200,symbols.length);
			}
			else{
				List[String]();

			}
	}



	//	Let the user define which colums to retrive from yahoo

	def getCustomQuote(symbols:List[String], columns:List[String]) : List[Array[String]] =  {

			println("Yahoo Finance Caller : getCustomQuote")

			readYahoo(symbols,getFormatStringFromList(columns));


	}

	def getFormatStringFromList(columns:List[String]) : String = {

			var formatString:String = ""
				columns.foreach(columnName => {

					println(fields(columnName))
					formatString += fields(columnName)

				})
				//println(formatString)
				formatString
	}


}